/*
 * @Author: wangchao
 * @Date: 2024-10-08 08:49:16
 * @LastEditors: wangchao
 * @LastEditTime: 2024-10-08 14:06:33
 * @FilePath: \JD-RTT-Driver\applications\u_vfd.c
 * @Description:
 * Copyright (c) 2024 by Bingshan Guardian, All Rights Reserved.
 */
#include "u_vfd.h"
#include "u_app.h"
#include "u_app_start.h"
#include "u_params.h"
#include "u_data.h"

#define DBG_TAG "VFD"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

/**
 * @Description: 充电过程流量策略
 * @Param:
 * @Return:
 * @param {rt_uint16_t} eocv
 */
rt_uint16_t get_charge_minflow(rt_uint16_t eocv)
{
    rt_uint16_t normalized_voltage = (rt_uint16_t)(eocv / 10);

    if (normalized_voltage < 1357)
    {
        return 420;
    }
    else if (normalized_voltage < 1359)
    {
        return 450;
    }
    else
    {
        return 480;
    }
}

/**
 * @Description: 放电过程流量策略
 * @Param:
 * @Return:
 * @param {rt_uint16_t} eocv
 */
rt_uint16_t get_discharge_minflow(rt_uint16_t eocv)
{
    rt_uint16_t normalized_voltage = (rt_uint16_t)(eocv / 10);

    if (normalized_voltage < 1332)
    {
        return 480;
    }
    else if (normalized_voltage < 1348)
    {
        return 450;
    }
    else
    {
        return 420;
    }
}

/**
 * @Description:
 * @Param:
 * @Return:
 * @param :
 */
rt_uint16_t get_initial_charge_minflow(void)
{
    return 240;
}

rt_uint16_t get_standby_minflow(void)
{
    return 240;
}

rt_uint16_t get_mixing_liquid_minflow(void)
{
    return 240;
}

rt_bool_t ENABLE_VFD_FREQ_CONTROL = RT_FALSE;
VAR_VFD_CTRL_STEP current_vfd_ctrl_step = VFD_HOLD_FREQ;
rt_uint16_t vfd_hold_freq_params = 300;

// 变频器实时设定值
typedef struct
{
    rt_uint16_t target_flow;
    rt_uint16_t current_flow;
    rt_uint16_t real_set_hz;
    rt_uint16_t lock_set_hz;
    rt_uint16_t last_lock_set_hz;
    rt_bool_t lock_flag;
    rt_uint16_t addr;
} VFD_Controller;

VFD_Controller pumps[4] = {
    {0, 0, 0, 0, 0, RT_FALSE, VFD_P1_ADDR},  // 正极泵1
    {0, 0, 0, 0, 0, RT_FALSE, VFD_P2_ADDR},  // 正极泵2
    {0, 0, 0, 0, 0, RT_FALSE, VFD_N1_ADDR},  // 负极泵1
    {0, 0, 0, 0, 0, RT_FALSE, VFD_N2_ADDR}   // 负极泵2
};

// 设置变频器频率
rt_bool_t vfd_set_freq(rt_uint16_t addr, rt_uint16_t freq)
{
    // 实现频率设定的通讯逻辑
    // 这里可以通过通讯发送 freq 到变频器
    return RT_TRUE;
}

// 频率保持处理器
rt_bool_t vfd_hold_freq_handler(void)
{
    vfd_hold_freq_params = 300;  // 设定保持频率
    for (int i = 0; i < 4; i++)
    {
        pumps[i].real_set_hz = vfd_hold_freq_params;
    }
    vfd_set_freq(VFD_P1_ADDR, vfd_hold_freq_params);
    vfd_set_freq(VFD_P2_ADDR, vfd_hold_freq_params);
    vfd_set_freq(VFD_N1_ADDR, vfd_hold_freq_params);
    vfd_set_freq(VFD_N2_ADDR, vfd_hold_freq_params);
    return RT_TRUE;
}

// 处理频率锁定
static void process_locking(VFD_Controller* pump)
{
    if (pump->lock_flag)
    {
        // 比较 lock_set_hz 和 last_lock_set_hz
        if (pump->lock_set_hz != pump->last_lock_set_hz)
        {
            vfd_set_freq(pump->addr, pump->lock_set_hz);
            pump->last_lock_set_hz = pump->lock_set_hz;  // 更新 last_lock_set_hz
        }
    }
    else
    {
        vfd_set_freq(pump->addr, pump->real_set_hz);
    }
}

// 限制频率值
static void vfd_set_value_limit(rt_uint16_t* sv)
{
    if (*sv > VFD_MAX_FREQ)
    {
        *sv = VFD_MAX_FREQ;
    }
}

// 更新泵控制逻辑
static void update_pump_control(VFD_Controller* pump)
{
    if (pump->current_flow < pump->target_flow)
    {
        pump->real_set_hz += 1;
        pump->lock_flag = RT_FALSE;
    }
    else
    {
        pump->lock_set_hz = pump->real_set_hz;
        pump->lock_flag = RT_TRUE;
    }
    vfd_set_value_limit(&pump->real_set_hz);
}

// 流量保持控制器
rt_bool_t vfd_hold_flow_handler(void)
{
    VAR_APP_START_MODE app_start_mode = get_current_app_start_mode();
    rt_uint16_t target_minflow = 0;

    rt_uint16_t eocv = 0;
    // 根据系统模式设定目标流量
    switch (app_start_mode)
    {
        case START_DO_INITIAL_CHARGE:
            target_minflow = get_initial_charge_minflow();
            break;
        case START_DO_STANDBY:
            target_minflow = get_standby_minflow();
            break;
        case START_DO_LIQUID_MIXING:
            target_minflow = get_mixing_liquid_minflow();
            break;
        case START_DO_CHARGING:
            target_minflow = get_charge_minflow(eocv);
            break;
        case START_DO_DISCHARGING:
            target_minflow = get_discharge_minflow(eocv);
            break;
        default:
            break;
    }

    // 更新所有泵的目标流量
    for (rt_uint8_t i = 0; i < 4; i++)
    {
        pumps[i].target_flow = target_minflow;
    }

    // 读取传感器的实时流量值
    pumps[0].current_flow = app_sensor_data.p1_flow;
    pumps[1].current_flow = app_sensor_data.p2_flow;
    pumps[2].current_flow = app_sensor_data.n1_flow;
    pumps[3].current_flow = app_sensor_data.n2_flow;

    // 更新泵的控制逻辑
    for (rt_uint8_t i = 0; i < 4; i++)
    {
        update_pump_control(&pumps[i]);
        process_locking(&pumps[i]);
    }
    return RT_TRUE;
}

void vfd_freq_control_thread_init(void)
{
    // 初始化泵的地址和初始状态
    pumps[0] = (VFD_Controller) {0, 0, 0, 0, 0, RT_FALSE, VFD_P1_ADDR};  // 正极泵1
    pumps[1] = (VFD_Controller) {0, 0, 0, 0, 0, RT_FALSE, VFD_P2_ADDR};  // 正极泵2
    pumps[2] = (VFD_Controller) {0, 0, 0, 0, 0, RT_FALSE, VFD_N1_ADDR};  // 负极泵1
    pumps[3] = (VFD_Controller) {0, 0, 0, 0, 0, RT_FALSE, VFD_N2_ADDR};  // 负极泵2
    //
    current_vfd_ctrl_step = VFD_HOLD_FREQ;
}

void vfd_freq_control_thread_entry(void)
{
    rt_tick_t holding_time = 0;
    rt_tick_t wait_freq_timestamp = 0;
    rt_tick_t wait_flow_timestamp = 0;
    vfd_freq_control_thread_init();
    //
    while (1)
    {
        if (ENABLE_VFD_FREQ_CONTROL)
        {
            switch (current_vfd_ctrl_step)
            {
                case VFD_HOLD_FREQ:
                    if (vfd_hold_freq_handler())
                    {
                        wait_freq_timestamp = rt_tick_get();
                        current_vfd_ctrl_step = VFD_HOLD_FREQ_WAIT;
                    }
                    break;
                case VFD_HOLD_FREQ_WAIT:
                    holding_time = (rt_tick_t)(30) * 1000;
                    if ((rt_tick_get() - wait_freq_timestamp) > holding_time)
                    {
                        current_vfd_ctrl_step = VFD_HOLD_FLOW;
                    }
                    break;
                case VFD_HOLD_FLOW:
                    if (vfd_hold_flow_handler())
                    {
                        wait_flow_timestamp = rt_tick_get();
                        current_vfd_ctrl_step = VFD_HOLD_FLOW_WAIT;
                    }
                    break;
                case VFD_HOLD_FLOW_WAIT:
                    holding_time = (rt_tick_t)(2) * 1000;
                    if ((rt_tick_get() - wait_flow_timestamp) > holding_time)
                    {
                        current_vfd_ctrl_step = VFD_HOLD_FLOW;
                    }
                    break;
                default:
                    break;
            }
        }
        else
        {
            LOG_I("Break VFDC Thread");
            break;
        }
    }
    LOG_I("VFDC Thread Quit Complete.");
}

int create_vfd_freq_control_thread(void)
{
    rt_thread_t thread_id = RT_NULL;

    thread_id = rt_thread_create("vfd", vfd_freq_control_thread_entry, RT_NULL, 1024, 15, 20);
    if (thread_id != RT_NULL)
    {
        rt_thread_startup(thread_id);
    }
    else
    {
        goto __exit;
    }
    return RT_EOK;

__exit:
    if (thread_id)
        rt_thread_delete(thread_id);
    return RT_ERROR;
}
